package com.smmisia.article.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smmisia.article.entity.AttractionScenicSpot;
import com.smmisia.article.entity.ScenicSpot;
import com.smmisia.article.entity.convetor.ScenicSpotConvertor;
import com.smmisia.article.exception.customException;
import com.smmisia.article.mapper.AttractionScenicSpotMapper;
import com.smmisia.article.request.ScenicSpotCreateRequest;
import com.smmisia.article.request.ScenicSpotUpdateRequest;
import com.smmisia.article.response.ScenicSpotResponse;
import com.smmisia.article.service.ScenicSpotService;
import com.smmisia.article.mapper.ScenicSpotMapper;
import com.smmisia.common.Result.Result;
import io.lettuce.core.RedisClient;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Collections;
import java.util.List;


@Service
public class ScenicSpotServiceImpl extends ServiceImpl<ScenicSpotMapper, ScenicSpot>
        implements ScenicSpotService, InitializingBean {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private AttractionScenicSpotMapper attractionScenicSpotMapper;

    @Autowired
    private ScenicSpotMapper scenicSpotMapper;

    private RBloomFilter<String> bloomFilter;

    @Override
    public Result<Boolean> create(ScenicSpotCreateRequest request) {
        Assert.isTrue(!bloomFilter.contains(request.getScenicSpotName()), () -> new customException("景区已存在"));
        ScenicSpot scenicSpot = ScenicSpot.create(request);
        boolean save = this.save(scenicSpot);
        Assert.isTrue(save, () -> new customException("景区创建失败"));
        bloomFilter.add(request.getScenicSpotName());
        return Result.ok(save);
    }

    @Override
    public Result<Boolean> updateScenicSpot(ScenicSpotUpdateRequest request) {
        Assert.notNull(scenicSpotMapper.selectById(request.getId()), () -> new customException("景区不存在"));
        ScenicSpot scenicSpot = ScenicSpotConvertor.INSTANCE.toEntity(request);
        int result = scenicSpotMapper.updateById(scenicSpot);
        Assert.isTrue(result > 0, () -> new customException("景区更新失败"));
        return Result.ok(true);
    }

    @Override
    public Result<Boolean> deleteScenicSpot(Integer id) {
        Assert.notNull(scenicSpotMapper.selectById(id), () -> new customException("景区不存在"));
        List<AttractionScenicSpot> attractionScenicSpots =
                attractionScenicSpotMapper.selectList(Wrappers.lambdaQuery(AttractionScenicSpot.class)
                .eq(AttractionScenicSpot::getScenicSpotId, id));
        Assert.isTrue(attractionScenicSpots.size() == 0, () -> new customException("景区已关联景点，无法删除"));
        int delete = scenicSpotMapper.delete(Wrappers.lambdaQuery(ScenicSpot.class)
                .eq(ScenicSpot::getId, id)
                .eq(ScenicSpot::getUserId, StpUtil.getLoginIdAsInt()));
        Assert.isTrue(delete > 0, () -> new customException("景区删除失败"));
        return Result.ok(true);
    }

    @Override
    public Result<ScenicSpotResponse> getScenicSpotById(Integer id) {
        ScenicSpot scenicSpot = scenicSpotMapper.selectById(id);
        Assert.notNull(scenicSpot, () -> new customException("景区不存在"));
        return Result.ok(ScenicSpotConvertor.INSTANCE.toResponse(scenicSpot));
    }

    @Override
    public Result<List<ScenicSpotResponse>> listScenicSpot() {
        List<ScenicSpot> scenicSpots = scenicSpotMapper.selectList(null);
        if(scenicSpots.size() == 0){
            return Result.ok(Collections.EMPTY_LIST);
        }
        return Result.ok(ScenicSpotConvertor.INSTANCE.toResponseList(scenicSpots));

    }

    @Override
    public Result<List<ScenicSpotResponse>> getScenicSpotByAddress(Integer address) {
        List<ScenicSpot> scenicSpots = scenicSpotMapper.selectList(Wrappers.lambdaQuery(ScenicSpot.class)
                .eq(ScenicSpot::getAddress, address));
        if(scenicSpots.size() == 0){
            return Result.ok(Collections.EMPTY_LIST);
        }
        return Result.ok(ScenicSpotConvertor.INSTANCE.toResponseList(scenicSpots));
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        bloomFilter = redissonClient.getBloomFilter("scenicSpot");
    }
}




